/*Copyright (C) 2013-2022 LZE*/
#include<bits/stdc++.h>
#define fo(x) freopen(#x".in","r",stdin); freopen(#x".out","w",stdout);
#define INF 0x7fffffff
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N = 1000010;
const int M = 100010;
ll T,n,m;
struct GraphEdge{
    ll to,next,w;
    GraphEdge() {}
}edge[M];
ll head[N] = {0},cnt = 0;
void add(ll u,ll v){
    edge[++cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
}
ll dfn[N] = {0},low[N] = {0};
ll time_ = 0;
bool vis[N] = {0},instack[N] = {0};
stack<ll> GraphNode;
ll sc = 0;
vector<ll> SCC[N];
ll SCCsize[N] = {0};
void Tarjan(ll step){
    low[step] = dfn[step] = ++time_;
    vis[step] = true;
    ll t;
    GraphNode.push(step); instack[GraphNode.top()] = true;
    for(ll i = head[step];i;i = edge[i].next){
        t = edge[i].to;
        if(!vis[t]){
            Tarjan(t);
            low[step] = min(low[step],low[t]);
        }
        else if(instack[t]) low[step] = min(low[step],low[t]);
    }
    if(dfn[step] == low[step]){
        sc++;
        while(GraphNode.top() != step){
            SCC[sc].push_back(GraphNode.top());
            SCCsize[sc]++;
            instack[GraphNode.top()] = false;
            GraphNode.pop();
        };
        SCC[sc].push_back(GraphNode.top());
        SCCsize[sc]++;
        instack[GraphNode.top()] = false;
        GraphNode.pop();
    }
}
int main() {
    scanf("%lld%lld",&n,&m);
    ll u,v,w;
    for(ll i = 1;i <= m;i++){
        scanf("%lld%lld%lld",&u,&v,&w);
        switch(w){
        case 1 : { add(u,v); break; }
        case 2 : { add(u,v); add(v,u); break; }
        }
    }
    for(ll i = 1;i <= n;i++)
        if(!vis[i]) Tarjan(i);
    ll maxn_ = 0;
    for(ll i = 1;i <= sc;i++){
        if(SCCsize[i] >= SCCsize[maxn_]){
            maxn_ = i;
        }
    }
    cout << SCCsize[maxn_] << endl;
    sort(SCC[maxn_].begin(),SCC[maxn_].end());
    for(ll i = 0;i < SCCsize[maxn_];i++){
        cout << SCC[maxn_][i] << " ";
    }
    cout << endl;
    return 0;
}
